package net.maku.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import net.maku.framework.common.excel.ExcelFinishCallBack;
import net.maku.framework.common.utils.ExcelUtils;
import net.maku.framework.common.utils.PageResult;
import net.maku.framework.common.utils.Result;
import net.maku.framework.mybatis.service.impl.BaseServiceImpl;
import net.maku.convert.MainOrderConvert;
import net.maku.entity.MainOrderEntity;
import net.maku.framework.security.user.SecurityUser;
import net.maku.framework.security.user.UserDetail;
import net.maku.query.MainOrderQuery;
import net.maku.security.service.UserDetailsServiceImpl;
import net.maku.system.entity.SysUserChargeEntity;
import net.maku.system.entity.SysUserDiscountEntity;
import net.maku.system.entity.SysUserWalletEntity;
import net.maku.system.service.SysUserChargeService;
import net.maku.system.service.SysUserDiscountService;
import net.maku.system.service.SysUserWalletService;
import net.maku.vo.MainOrderExcelVO;
import net.maku.vo.MainOrderVO;
import net.maku.dao.MainOrderDao;
import net.maku.service.MainOrderService;
import net.maku.websocket.message.JsonDataMessage;
import net.maku.websocket.sender.WebSocketMessageSender;
import net.maku.websocket.vo.MessageVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 订单
 *
 * @author 小陈 
 * @since 1.0.0 2025-03-17
 */
@Service
@AllArgsConstructor
public class MainOrderServiceImpl extends BaseServiceImpl<MainOrderDao, MainOrderEntity> implements MainOrderService {

    private final WebSocketMessageSender webSocketMessageSender;
    private final UserDetailsServiceImpl userDetailsServiceImpl;
    private final SysUserWalletService sysUserWalletService;
    private final SysUserDiscountService sysUserDiscountService;
    private final SysUserChargeService  sysUserChargeService;

    @Override
    public PageResult<MainOrderVO> page(MainOrderQuery query) {
        IPage<MainOrderEntity> page = baseMapper.selectPage(getPage(query), getWrapper(query));
        return new PageResult<>(MainOrderConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }

    @Override
    public PageResult<MainOrderVO> pageList(MainOrderQuery query) {
        IPage<MainOrderEntity> page = baseMapper.selectPage(getPage(query), getWrapperQuery(query));
        return new PageResult<>(MainOrderConvert.INSTANCE.convertList(page.getRecords()), page.getTotal());
    }

    private LambdaQueryWrapper<MainOrderEntity> getWrapper(MainOrderQuery query){
        LambdaQueryWrapper<MainOrderEntity> wrapper = Wrappers.lambdaQuery();
        return wrapper;
    }
    private LambdaQueryWrapper<MainOrderEntity> getWrapperQuery(MainOrderQuery query){
        //添加条件查询
        LambdaQueryWrapper<MainOrderEntity> wrapper = Wrappers.lambdaQuery();
        if (StringUtils.isNotBlank(query.getSendCountry())){
            wrapper.eq(MainOrderEntity::getSendCountry,query.getSendCountry());
        }if (StringUtils.isNotBlank(query.getGoalCity())){
            wrapper.eq(MainOrderEntity::getGoalCity,query.getGoalCity());
        }if (StringUtils.isNotBlank(query.getSendCity())){
            wrapper.eq(MainOrderEntity::getSendCity,query.getSendCity());
        }if (StringUtils.isNotBlank(query.getSendProvince())){
            wrapper.eq(MainOrderEntity::getSendProvince,query.getSendProvince());
        }if (StringUtils.isNotBlank(query.getGoalCountry())){
            wrapper.eq(MainOrderEntity::getGoalCountry,query.getGoalCountry());
        }if (StringUtils.isNotBlank(query.getCatalog())){
            wrapper.eq(MainOrderEntity::getCatalog,query.getCatalog());
        }
        return wrapper;
    }

    @Override
    public void save(MainOrderVO vo) {
        MainOrderEntity entity = MainOrderConvert.INSTANCE.convert(vo);
        baseMapper.insert(entity);
    }

    @Override
    public void update(MainOrderVO vo) {
        MainOrderEntity entity = MainOrderConvert.INSTANCE.convert(vo);
        updateById(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> purchaseList(List<Long> idList) {
        // 购买过程 查看余额是否足够-》扣除金额-》存入购买表-》记录购买记录-》删除订单表-》返回余额和购买成功信息
        // 登录用户信息
        UserDetail user = SecurityUser.getUser();
        List<MainOrderEntity> mainOrderEntities = baseMapper.selectBatchIds(idList);
        BigDecimal totalPrice = mainOrderEntities.stream().map(MainOrderEntity::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
        if (totalPrice.compareTo(user.getTotalPrice())==1){
            return Result.error("余额不足!");
        }
        BigDecimal totalPriceAfter = totalPrice;
        List<SysUserWalletEntity> sysUserWalletEntities = new ArrayList<>();
        List<MainOrderEntity> mainOrderEntitiesAfter = new ArrayList<>();
        // 记录购买记录
        List<SysUserDiscountEntity> list = sysUserDiscountService.list(new LambdaQueryWrapper<SysUserDiscountEntity>().eq(SysUserDiscountEntity::getUserId,user.getId()));
        if (list.size() > 0){
            BigDecimal finalTotalPrice = BigDecimal.ZERO;
            List<MainOrderEntity> list1 = mainOrderEntities;
            list.forEach(i->{
                List<MainOrderEntity> mainOrderEntityList = mainOrderEntities.stream().filter(j -> j.getCatalog().equals(i.getCatalog())).toList();
                if (mainOrderEntityList.size() > 0){
                    BigDecimal props = BigDecimal.ZERO;
                    props.add(mainOrderEntityList.stream().map(MainOrderEntity::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
                    //打折
                    finalTotalPrice.add(props.multiply(i.getProp()));
                    list1.removeAll(mainOrderEntityList);
                    mainOrderEntities.forEach(j->{
                        j.setRealPrice(j.getPrice().multiply(i.getProp()));
                    });
                    mainOrderEntitiesAfter.addAll(mainOrderEntityList);
                }
            });
            mainOrderEntitiesAfter.addAll(list1);
            finalTotalPrice.add(list1.stream().map(MainOrderEntity::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add));
            totalPriceAfter = finalTotalPrice;
        }else {
            mainOrderEntitiesAfter.addAll(mainOrderEntities);
        }
        baseMapper.deleteByIds(mainOrderEntities.stream().map(MainOrderEntity::getId).toList());
        //存入购买记录
        SysUserChargeEntity sysUserChargeEntity = new SysUserChargeEntity();
        sysUserChargeEntity.setRechargeUser(user.getId());
        //记录扣费记录
        sysUserChargeEntity.setRechargeUser(1L);
        sysUserChargeEntity.setLastAmount(totalPrice);
        sysUserChargeEntity.setNextAmount(totalPriceAfter);
        sysUserChargeEntity.setRechargeAmount(totalPrice.subtract(totalPriceAfter));
        sysUserChargeService.save(sysUserChargeEntity);
        // 扣除余额
        user.setTotalPrice(totalPriceAfter);
        // 存入购买订单
        mainOrderEntitiesAfter.forEach(i->{
            SysUserWalletEntity sysUserWalletEntity = new SysUserWalletEntity();
            BeanUtil.copyProperties(i,sysUserWalletEntity);
            sysUserWalletEntity.setBuyStatus(1);
            sysUserWalletEntity.setBuyId(user.getId());
            sysUserWalletEntities.add(sysUserWalletEntity);
        });
        sysUserWalletService.saveBatch(sysUserWalletEntities);
        return Result.ok("购买成功!");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> buy(Long id) {
        // 购买过程 查看余额是否足够-》扣除金额-》存入购买表-》记录购买记录-》删除订单表-》返回余额和购买成功信息
        // 登录用户信息
        UserDetail user = SecurityUser.getUser();
        MainOrderEntity mainOrderEntity = baseMapper.selectById(id);
        if (mainOrderEntity.getPrice().compareTo(user.getTotalPrice())==1){
            return Result.error("余额不足!");
        }
        BigDecimal discount = new BigDecimal(1);
        // 记录购买记录
        List<SysUserDiscountEntity> list = sysUserDiscountService.list(new LambdaQueryWrapper<SysUserDiscountEntity>()
                .eq(SysUserDiscountEntity::getUserId, user.getId()).eq(SysUserDiscountEntity::getCatalog, mainOrderEntity.getCatalog()));
        if (list.size() > 0){
            discount = list.get(0).getProp();
        }
        baseMapper.deleteById(id);
        //存入购买记录
        SysUserChargeEntity sysUserChargeEntity = new SysUserChargeEntity();
        sysUserChargeEntity.setRechargeUser(user.getId());
        //记录扣费记录
        sysUserChargeEntity.setRechargeUser(1L);
        sysUserChargeEntity.setLastAmount(user.getTotalPrice());
        sysUserChargeEntity.setNextAmount(user.getTotalPrice().subtract(mainOrderEntity.getPrice().multiply(discount)));
        sysUserChargeEntity.setRechargeAmount(mainOrderEntity.getPrice().multiply(discount));
        sysUserChargeService.save(sysUserChargeEntity);
        // 扣除余额
        user.setTotalPrice(sysUserChargeEntity.getNextAmount());
        // 存入购买订单
        SysUserWalletEntity sysUserWalletEntity = new SysUserWalletEntity();
        BeanUtil.copyProperties(mainOrderEntity,sysUserWalletEntity);
        sysUserWalletEntity.setBuyStatus(1);
        sysUserWalletEntity.setBuyId(user.getId());
        sysUserWalletService.save(sysUserWalletEntity);
        return Result.ok("购买成功!");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<Long> idList) {
        removeByIds(idList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<MainOrderVO> importByExcel(MultipartFile file) {
        Long userId = SecurityUser.getUserId();
        MessageVO messageVO = new MessageVO();
        messageVO.setName("进度条");
        List<MainOrderVO> mainOrderVOList = new ArrayList<>();
        ExcelUtils.readAnalysis(file, MainOrderExcelVO.class, new ExcelFinishCallBack<>() {
            @Override
            public void doSaveBatch(List<MainOrderExcelVO> result) {
                ExcelUtils.parseDict(result);
                AtomicInteger count = new AtomicInteger();
                result.forEach(i->{
                    LambdaQueryWrapper<MainOrderEntity> wrapper = new LambdaQueryWrapper<>();
                    wrapper = !Objects.equals(i.getStartTime(),null) ? wrapper.ge(MainOrderEntity::getSendTime,i.getStartTime()) : wrapper;
                    wrapper = !Objects.equals(i.getEndTime(),null) ? wrapper.le(MainOrderEntity::getSendTime,i.getEndTime()) : wrapper;
                    wrapper = !Objects.equals(i.getOrderNumber(),null) ? wrapper.eq(MainOrderEntity::getOrderNumber,i.getOrderNumber()) : wrapper;
                    wrapper.last("LIMIT 1");
                    // todo 继续添加条件
                    MainOrderEntity mainOrderEntity = baseMapper.selectOne(wrapper);
                    if (mainOrderEntity == null){
                        return;
                    }
                    mainOrderVOList.add(MainOrderConvert.INSTANCE.convert(mainOrderEntity));
                    // 完成度展示
                    count.getAndIncrement();
                    messageVO.setContent("当前进度："+count.get()+"/"+result.size());
                    JsonDataMessage<MessageVO> message = new JsonDataMessage<>();
                    message.setData(messageVO);
                    webSocketMessageSender.send(userId,message);
                });
            }
        });
        return mainOrderVOList;
    }
}